﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using RedBit.UserVoice.OAuth;
using Hammock;
using Hammock.Web;
using Newtonsoft.Json.Linq;
using RedBit.UserVoice.Model;
using System.Collections.Generic;

namespace RedBit.UserVoice.Services
{
    public class UVUserService : BaseUVApi
    {

        public static bool IsLoggedIn
        {
            get
            {
                return UserVoiceAPI.AccessToken != null;
            }
        }

        #region Create User

        public static void CreateUser(OAuthUser user, Action<UVResponse<OAuthUser>> responseHandler)
        {
            UVOAuthService.GetRequestToken(rt => CreateUser(rt, user, responseHandler));
        }

        public static void CreateUser(RequestToken token, OAuthUser user, Action<UVResponse<OAuthUser>> responseHandler)
        {
            var credentials = BuildCredentials();

            var client = new RestClient
            {
                Authority = string.Format(UserVoiceConstants.URL_TEMPLATE, UserVoiceAPI.AppName),
                Credentials = credentials,
                Method = WebMethod.Post
            };

            var request = new RestRequest
            {
                Path = UserVoiceConstants.CREATE_USER_SUFFIX,
            };

            request.AddParameter("user%5Bname%5D", user.Name);
            request.AddParameter("user%5Bemail%5D", user.Email);
            request.AddParameter("user%5Bguid%5D", user.Guid);
            request.AddParameter("request_token", token.Key);


            client.BeginRequest(request, HandleOAuthAccessToken, responseHandler);
        }

        private static void HandleOAuthAccessToken(RestRequest rq, RestResponse rs, object token)
        {
            //TODO: Handle Errors
            var handler = token as Action<UVResponse<OAuthUser>>;

            JObject obj = JObject.Parse(rs.Content);

            OAuthUser user;

            if (obj["errors"] == null || !obj["errors"].HasValues)
            {
                var rt = new RequestToken()
                {
                    Key = obj["token"]["oauth_token"].Value<string>(),
                    Secret = obj["token"]["oauth_token_secret"].Value<string>()
                };

                UserVoiceAPI.AccessToken = rt;
            
                user = new OAuthUser()
                {
                    //TODO: Parse the rest of the object.
                    Id = obj["user"]["id"].Value<string>(),
                    AvatarUrl = obj["user"]["avatar_url"].Value<string>(),
                    Name = obj["user"]["name"].Value<string>(),
                    Email = obj["user"]["email"].Value<string>()
                };
            }
            else
            {
                user = new OAuthUser();
            }

            var error = ParseError(obj);
            handler(new UVResponse<OAuthUser> { Model = user, Error = error });

        }
        #endregion Create User

        #region GetCurrentUser
        public static void GetCurrentUser(Action<UVResponse<OAuthUser>> responseHandler)
        {
            var credentials = BuildCredentials();

            credentials.Token = UserVoiceAPI.AccessToken.Key;
            credentials.TokenSecret = UserVoiceAPI.AccessToken.Secret;

            var client = new RestClient
            {
                Authority = string.Format(UserVoiceConstants.URL_TEMPLATE, UserVoiceAPI.AppName),
                Credentials = credentials
            };

            var request = new RestRequest
            {
                Path = UserVoiceConstants.CURRENT_USER_SUFFIX,
            };



            client.BeginRequest(request, HandleCurrentUserResponse, responseHandler);
        }

        private static void HandleCurrentUserResponse(RestRequest rq, RestResponse rs, object token)
        {
            //TODO: Handle Errors
            var handler = token as Action<UVResponse<OAuthUser>>;

            JObject obj = JObject.Parse(rs.Content);

            OAuthUser user = new OAuthUser()
            {
                //TODO: Parse the rest of the object.
                Id = obj["user"]["id"].Value<string>(),
                AvatarUrl = obj["user"]["avatar_url"].Value<string>(),
                Name = obj["user"]["name"].Value<string>(),
                Email = obj["user"]["email"].Value<string>(),
                KarmaScore = obj["user"]["karma_score"].Value<int>(),
                CreatedSuggestionsCount = obj["user"]["created_suggestions_count"].Value<int>(),
                SupportedSuggestions = new List<UVSupportedSuggestions>()
            };

            var forums = obj["user"]["visible_forums"];

            user.Forums = new List<UVForum>();

            if( forums != null && forums.HasValues )
            {
                foreach( var forum in forums)
                {
                    user.Forums.Add(new UVForum()
                    {
                        Name = forum["name"].Value<string>(),
                        Id = forum["id"].Value<string>()
                    });

                    var forumActivity = forum["forum_activity"];

                    foreach( var ss in forumActivity["supported_suggestions"] )
                    {
                        user.SupportedSuggestions.Add(new UVSupportedSuggestions()
                        {
                            Id = ss["id"].Value<string>(),
                            Votes = ss["votes"].Value<int>(),
                            ForumId = forum["id"].Value<string>()
                        });
                    }
                }
            }           

            var error = ParseError(obj);
            handler(new UVResponse<OAuthUser> { Model = user, Error = error });

        }
        #endregion GetCurrentUser
    }
}
